HVM_SAVE_ALL_NOSEGREGS
STGI
+.globl svm_stgi_label;
+svm_stgi_label:
movl %esp,%eax
push %eax
call svm_vmexit_handler
VMLOAD
STGI
+.globl svm_stgi_label;
+svm_stgi_label:
movq %rsp,%rdi
call svm_vmexit_handler
jmp svm_asm_do_resume
#include <xen/sched.h>
#include <asm/regs.h>
#include <asm/current.h>
+#include <asm/hvm/support.h>
#include "op_x86_model.h"
#include "op_counter.h"
extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
int mode, int event);
-
+extern int xenoprofile_get_mode(struct vcpu *v,
+ struct cpu_user_regs * const regs);
+
+extern char svm_stgi_label[];
+
static void athlon_fill_in_addresses(struct op_msrs * const msrs)
{
msrs->counters[0].addr = MSR_K7_PERFCTR0;
}
}
-
static int athlon_check_ctrs(unsigned int const cpu,
- struct op_msrs const * const msrs,
- struct cpu_user_regs * const regs)
+ struct op_msrs const * const msrs,
+ struct cpu_user_regs * const regs)
{
unsigned int low, high;
int ovf = 0;
unsigned long eip = regs->eip;
int mode = 0;
-
- if (guest_kernel_mode(current, regs))
- mode = 1;
- else if (ring_0(regs))
- mode = 2;
+ struct vcpu *v = current;
+ struct cpu_user_regs tmp_regs;
+
+ if (!guest_mode(regs) &&
+ (regs->eip == (unsigned long)svm_stgi_label)) {
+ /* SVM guest was running when NMI occurred */
+ hvm_store_cpu_guest_regs(v, &tmp_regs, NULL);
+ eip = tmp_regs.eip;
+ mode = xenoprofile_get_mode(v, &tmp_regs);
+ } else {
+ eip = regs->eip;
+ mode = xenoprofile_get_mode(v, regs);
+ }
for (i = 0 ; i < NUM_COUNTERS; ++i) {
CTR_READ(low, high, msrs, i);
}
}
-
extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
int mode, int event);
+extern int xenoprofile_get_mode(struct vcpu *v,
+ struct cpu_user_regs * const regs);
static int p4_check_ctrs(unsigned int const cpu,
struct op_msrs const * const msrs,
int i;
int ovf = 0;
unsigned long eip = regs->eip;
- int mode = 0;
-
- if (guest_kernel_mode(current, regs))
- mode = 1;
- else if (ring_0(regs))
- mode = 2;
+ int mode = xenoprofile_get_mode(current, regs);
stag = get_stagger();
}
}
-
extern void xenoprof_log_event(struct vcpu *v, unsigned long eip,
int mode, int event);
+extern int xenoprofile_get_mode(struct vcpu *v,
+ struct cpu_user_regs * const regs);
static int ppro_check_ctrs(unsigned int const cpu,
struct op_msrs const * const msrs,
int i;
int ovf = 0;
unsigned long eip = regs->eip;
- int mode = 0;
+ int mode = xenoprofile_get_mode(current, regs);
- if ( guest_kernel_mode(current, regs) )
- mode = 1;
- else if ( ring_0(regs) )
- mode = 2;
-
for (i = 0 ; i < NUM_COUNTERS; ++i) {
CTR_READ(low, high, msrs, i);
if (CTR_OVERFLOWED(low)) {
#include <xen/guest_access.h>
#include <xen/sched.h>
#include <public/xenoprof.h>
+#include <asm/hvm/support.h>
#include "op_counter.h"
}
}
-char *alloc_xenoprof_buf(struct domain *d, int npages)
+static char *alloc_xenoprof_buf(struct domain *d, int npages)
{
char *rawbuf;
int i, order;
return rawbuf;
}
-int alloc_xenoprof_struct(struct domain *d, int max_samples, int is_passive)
+static int alloc_xenoprof_struct(
+ struct domain *d, int max_samples, int is_passive)
{
struct vcpu *v;
int nvcpu, npages, bufsize, max_bufsize;
d->xenoprof = NULL;
}
-int active_index(struct domain *d)
+static int active_index(struct domain *d)
{
int i;
return -1;
}
-int set_active(struct domain *d)
+static int set_active(struct domain *d)
{
int ind;
struct xenoprof *x;
return 0;
}
-int reset_active(struct domain *d)
+static int reset_active(struct domain *d)
{
int ind;
struct xenoprof *x;
return 0;
}
-void reset_passive(struct domain *d)
+static void reset_passive(struct domain *d)
{
struct xenoprof *x;
return;
}
-void reset_active_list(void)
+static void reset_active_list(void)
{
int i;
activated = 0;
}
-void reset_passive_list(void)
+static void reset_passive_list(void)
{
int i;
pdomains = 0;
}
-int add_active_list (domid_t domid)
+static int add_active_list(domid_t domid)
{
struct domain *d;
return 0;
}
-int add_passive_list(XEN_GUEST_HANDLE(void) arg)
+static int add_passive_list(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_passive passive;
struct domain *d;
}
}
-int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
+static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_init xenoprof_init;
int ret;
return 0;
}
-int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
+static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_get_buffer xenoprof_get_buffer;
struct domain *d = current->domain;
return ret;
}
+int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs)
+{
+ if ( !guest_mode(regs) )
+ return 2;
+
+ if ( hvm_guest(v) )
+ return ((regs->cs & 3) != 3);
+
+ return guest_kernel_mode(v, regs);
+}
+
/*
* Local variables:
* mode: C